/**
 * @author Fang Lu, fanglupku@gmail.com
 * 2011-4-12
 */
package dao;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import persist.RefPageDB;
import util.StringDealer;

import code.extract.BasePageDealer;
import code.extract.CEConfig;
import code.extract.CodeExtractor;
import code.extract.FileDealer;
import code.extract.PageClassifier;
import code.extract.SegmentItem;

import dao.entity.PageEntity;
import dao.entity.SegmentEntity;

public class PageDao extends BaseDao{
	public static boolean insertPage(Connection conn, PageEntity page){
		String sqlString = "insert into page (id,link,title,meta_description,meta_keywords,page_type,state) values(?,?,?,?,?,?,?)";
		PreparedStatement pstmt;
		try {
			pstmt = conn.prepareStatement(sqlString);
			pstmt.setInt(1, page.getId());
			pstmt.setString(2, StringDealer.getStringForMaxLength(250, page.getLink()));
			pstmt.setString(3, StringDealer.getStringForMaxLength(250, page.getTitle()));
			pstmt.setString(4, StringDealer.getStringForMaxLength(5000, page.getMeta_description()));
			pstmt.setString(5, StringDealer.getStringForMaxLength(5000, page.getMeta_keywords()));
			pstmt.setInt(6, page.getPage_type());
			pstmt.setInt(7, page.getState());
			pstmt.executeUpdate();
			pstmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	public static boolean updatePage(Connection conn, PageEntity page){
		if (page.getId() < 0){
			return false;
		}
		String sqlString = "update page set link=?,title=?,meta_description=?,meta_keywords=?,page_type=?,state=? where id=?";
		PreparedStatement pstmt;
		try {
			pstmt = conn.prepareStatement(sqlString);
			pstmt.setString(1, StringDealer.getStringForMaxLength(250, page.getLink()));
			pstmt.setString(2, StringDealer.getStringForMaxLength(250, page.getTitle()));
			pstmt.setString(3, StringDealer.getStringForMaxLength(5000, page.getMeta_description()));
			pstmt.setString(4, StringDealer.getStringForMaxLength(5000, page.getMeta_keywords()));
			pstmt.setInt(5, page.getPage_type());
			pstmt.setInt(6, page.getState());
			pstmt.setInt(7, page.getId());
			pstmt.executeUpdate();
			pstmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	public static int insertPage(Connection conn, ArrayList<PageEntity> pageList){
		int okNum = 0;
		String sqlString = "insert into page (id,link,title,meta_description,meta_keywords,page_type,state) values(?,?,?,?,?,?,?)";
		PreparedStatement pstmt;
		try {
			pstmt = conn.prepareStatement(sqlString);
			for (int i=0; i<pageList.size(); ++i){
				pstmt.setInt(1, pageList.get(i).getId());
				pstmt.setString(2, StringDealer.getStringForMaxLength(250, pageList.get(i).getLink()));
				pstmt.setString(3, StringDealer.getStringForMaxLength(250, pageList.get(i).getTitle()));
				pstmt.setString(4, StringDealer.getStringForMaxLength(5000, pageList.get(i).getMeta_description()));
				pstmt.setString(5, StringDealer.getStringForMaxLength(5000, pageList.get(i).getMeta_keywords()));
				pstmt.setInt(6, pageList.get(i).getPage_type());
				pstmt.setInt(7, pageList.get(i).getState());
				try{
					pstmt.executeUpdate();
					++ okNum;
				} catch (SQLException e1){
//					e1.printStackTrace();
				}
			}
			pstmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return okNum;
		}
		return okNum;
	}
	public static HashMap<String, PageEntity> getLinkMapPage(Connection conn, int linkType){
		HashMap<String, PageEntity> result = new HashMap<String, PageEntity>();
		HashSet<String> linkSet = new HashSet<String>();
		String sqlString = "select id,link,title,meta_description,meta_keywords,page_type,state from page where state=" + linkType;
		if (linkType < 0 || linkType == PageEntity.ALL){
			sqlString = "select id,link,title,meta_description,meta_keywords,page_type,state from page";
		}
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			while (resultSet.next()){
				int id = resultSet.getInt(1);
				String link = resultSet.getString(2);
				String title = resultSet.getString(3);
				String meta_description = resultSet.getString(4);
				String meta_keywords = resultSet.getString(5);
				int page_type = resultSet.getInt(6);
				int state = resultSet.getInt(7);
				if (linkSet.contains(link)){
					continue;
				}
				PageEntity thisPage = new PageEntity(id, link, title, 
						meta_description, meta_keywords, "", 
						page_type, state);
				result.put(link, thisPage);
				linkSet.add(link);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static ArrayList<String> getLinkList(Connection conn, int linkType){
		ArrayList<String> result = new ArrayList<String>();
		String sqlString = "select link from page where state=" + linkType;
		if (linkType < 0 || linkType == PageEntity.ALL){
			sqlString = "select link from page";
		}
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			while (resultSet.next()){
				String thisLink = resultSet.getString(1);
				result.add(thisLink);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static HashSet<String> getLinkSet(Connection conn, int linkType){
		HashSet<String> result = new HashSet<String>();
		String sqlString = "select link from page where state=" + linkType;
		if (linkType < 0 || linkType == PageEntity.ALL){
			sqlString = "select link from page";
		}
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			while (resultSet.next()){
				String thisLink = resultSet.getString(1);
				result.add(thisLink);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static int getMaxID(Connection conn){
		int result = -1;
		String sqlString = "select max(id) from page";
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			if (resultSet.next()){
				result = resultSet.getInt(1);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static int getPageCount(Connection conn, int linkType){
		int result = 0;
		String sqlString = "select count(id) from page where state=" + linkType;
		if (linkType < 0 || linkType == PageEntity.ALL){
			sqlString = "select count(id) from page";
		}
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			if (resultSet.next()){
				result = resultSet.getInt(1);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static HashMap<String, Integer> getLinkMapID(Connection conn){
		HashMap<String, Integer> result = new HashMap<String, Integer>();
		String sqlString = "select link,id from page";
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			while(resultSet.next()){
				String thisLink = resultSet.getString(1);
				int thisId = resultSet.getInt(2);
				result.put(thisLink, thisId);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static PageEntity getPageByID(Connection conn, int PageID){
		String sqlString = "select id, link, title, meta_description, meta_keywords, page_type, state from page where id = "+PageID;
		PageEntity pe = null;
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			while(resultSet.next()){
				int thisId = resultSet.getInt(1);
				String thisLink = resultSet.getString(2);
				String title = resultSet.getString(3);
				String meta_description = resultSet.getString(4);
				String meta_keywords = resultSet.getString(5);
				int page_type = resultSet.getInt(6);
				int state  = resultSet.getInt(7);
				pe = new PageEntity(thisId, thisLink, title, meta_description, meta_keywords, "", page_type, state);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return pe;
	}
	public static HashMap<Integer, String> getIDMapLink(Connection conn){
		HashMap<Integer, String> result = new HashMap<Integer, String>();
		String sqlString = "select link,id from page";
		try {
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(sqlString);
			while(resultSet.next()){
				String thisLink = resultSet.getString(1);
				int thisId = resultSet.getInt(2);
				result.put(thisId, thisLink);
			}
			resultSet.close();
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static void initPage(){
		//part 3. insert all page
		RefPageDB refDB = new RefPageDB(CEConfig.getRefPageBDBDirname(), 1024*1024, "utf8");
		refDB.open(CEConfig.getRefPageBDBDatabasename());
		refDB.openCursor();
		int totalCount = Integer.MAX_VALUE;
		int okNum = 0;
		try {
			Connection conn = getTestConn();
			int maxPageId = getMaxID(conn);
			System.out.println("maxPageId:" + maxPageId);
			int maxSeg = CEConfig.getCodeExtractMaxseg();
			int minSeg = CEConfig.getCodeExtractMinseg();
			ErrorPageRecorder error_recorder = new ErrorPageRecorder(CEConfig.getCodeExtractErrorFilename(), "utf8");
			HashSet<String> existLinkSet = getLinkSet(conn, PageEntity.ALL);
			PageEntity page = refDB.getNextPage();
			while (page != null && okNum < totalCount){
				try{
					if (!existLinkSet.contains(page.getLink())){
						page.setId(maxPageId+1);
						insertPage(conn, page);
						++ maxPageId;
						ArrayList<SegmentItem> segList = 
							CodeExtractor.extractCodeSegmentFromPage(page.getContent(), CodeExtractor.CONTINUAL_MERGE|CodeExtractor.SMALL_CODE_MERGE
									| CodeExtractor.EMPTY_MERGE);
						if (segList.size() > maxSeg || segList.size() < minSeg){
							error_recorder.addErrorPage(page.getLink());
						}else{
							for (int i=0; i<segList.size(); ++i){
								SegmentEntity thisSeg = new SegmentEntity(segList.get(i));
								thisSeg.setPage_id(page.getId());
								SegmentDao.insertSegment(conn, thisSeg);
							}
						}
						System.out.println("page_OK:" + okNum);
//						System.out.println(segList.size());
						++ okNum;
					}
					page = refDB.getNextPage();
				}catch (Exception e) {
					e.printStackTrace();
				}
				
			}
			conn.close();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		refDB.closeCursor();
		refDB.close();
	}
	
	public static void main(String args[]){
		//just test
//		String fileContent;
//		try {
//			
//			fileContent = FileDealer.getFileContent("C:\\Users\\ftc\\Desktop\\meta_description.htm");
////			ArrayList<String> mList = BasePageDealer.extractOneTagContent(fileContent, "meta", "name", "description");
//			
//			ArrayList<String> mList = BasePageDealer.extractOneTagContent(fileContent, "meta", "name", "description");
//			
//	    	String meta_desc = "";
//	    	if (mList.size() > 0){
//	    		meta_desc = mList.get(0);
//	    		meta_desc = BasePageDealer.extractAttribute(meta_desc, "content");
//	    	}
//	    	System.out.println(meta_desc);
//	    	
//	    	mList = BasePageDealer.extractOneTagContent(fileContent, "meta", "name", "keywords");
//	    	meta_desc = "";
//	    	if (mList.size() > 0){
//	    		meta_desc = mList.get(0);
//	    		meta_desc = BasePageDealer.extractAttribute(meta_desc, "content");
//	    	}
//	    	System.out.println(meta_desc);
////			ArrayList<String> mList = BasePageDealer.extractOneTagContent(fileContent, "meta");
//			
////			System.out.println(mList.size());
////			for (int i=0; i<mList.size(); ++i){
////				System.out.println(i + ":" +mList.get(i).length() + ":" + mList.get(i));
////			}
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
		
	}
}
